/*
 * Copyright (c) 2024. hallele, Inc All rights reserved.
 */

package cn.hallele.ms.infrastructure.core.convertor.das;

import cn.hallele.infrastructure.metadata.io.Page;
import cn.hallele.infrastructure.util.ObjectUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Model转换类<br>
 * O：目标层传操作类<br>
 * S：当前层操作实体类型<br>
 * T：目标层操作实体类型<br>
 *
 * @author anle5
 * @since 2024/9/15 0:18
 */
public abstract class ModelDas<O, S, T> {
    /**
     * 目标层传操作类
     */
    protected final O option;

    protected ModelDas(O option) {
        this.option = option;
    }

    /**
     * 将T转成E
     *
     * @param s 被转换者
     * @return S 转换后者
     */
    protected abstract T convert(S s);

    /**
     * 将E回转陈T
     *
     * @param t 被回转换者
     * @return S 回转换后者
     */
    protected abstract S revert(T t);

    /**
     * 将S类型List转成T类型List
     *
     * @param sList S类型List
     * @return T类型List
     */
    protected List<T> convertList(List<S> sList) {
        if (ObjectUtil.isEmpty(sList)) {
            return new ArrayList<>(0);
        }

        return sList.stream().map(this::convert).toList();
    }

    /**
     * 将S类型List回转成T类型List
     *
     * @param tList T类型List
     * @return S类型List
     */
    protected List<S> revertList(List<T> tList) {
        if (ObjectUtil.isEmpty(tList)) {
            return new ArrayList<>(0);
        }

        return tList.stream().map(this::revert).toList();
    }

    /**
     * 转换page，将S类型page转成T类型page
     *
     * @param page S类型page
     * @return T类型page
     */
    protected Page<T> convertPage(Page<S> page) {
        if (page == null) {
            return null;
        }

        return Page.<T>builder()
                .pageNo(page.getPageNo())
                .pageSize(page.getPageSize())
                .totalNum(page.getTotalNum())
                .totalPages(page.getTotalPages())
                .data(convertList(page.getData()))
                .build();
    }

    /**
     * 转换page，将T类型page回转成S类型page
     *
     * @param page T类型page
     * @return S类型page
     */
    protected Page<S> revertPage(Page<T> page) {
        if (page == null) {
            return null;
        }

        return Page.<S>builder()
                .pageNo(page.getPageNo())
                .pageSize(page.getPageSize())
                .totalNum(page.getTotalNum())
                .totalPages(page.getTotalPages())
                .data(revertList(page.getData()))
                .build();
    }

    /**
     * 将jpa的page T转成业务的page S
     *
     * @param page jpa提供的page对象
     * @return 业务的page对象
     */
    protected Page<S> revertPage(org.springframework.data.domain.Page<T> page) {
        return revertPage(Page.<T>builder()
                .pageNo(page.getNumber() + 1)
                .pageSize(page.getSize())
                .totalNum(page.getTotalElements())
                .totalPages(page.getTotalPages())
                .data(page.getContent())
                .build());
    }
}
